﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyAlbum.Model;
using System.Xml.Linq;
using MyAlbum.Utility;


namespace MyAlbum.Data.Xml
{
    public class EntranceRepository : XmlRepository, IRepository<MyAlbum.Model.Entrance>
    {
        private static object locker = "locker";

        public EntranceRepository(string rootPath)
            : base(rootPath, "Entrances")
        {
        }

        #region IDataFactory<Entrance> Members

        public List<MyAlbum.Model.Entrance> GetItems()
        {
            return this.Document.Descendants("Entrance").Select(s => new MyAlbum.Model.Entrance()
            {
                Id = s.Attribute("Id").Value,
                IP = s.Element("IP").Value.Trim(),
                Page = s.Element("Page").Value.Trim(),
                SessionId = s.Element("SessionId").Value.Trim(),
                Details = s.Element("Details").Value.Trim(),
                Timestamp = (DateTime)s.Element("Timestamp")
            }).ToList();
        }

        public void AddItem(MyAlbum.Model.Entrance item)
        {
            Assert.IsNotNull(item);
            Assert.IsNotNull(item.SessionId);
            Assert.IsNotNull(item.IP);
            Assert.IsNotNull(item.Page);
            item.Id = Guid.NewGuid().ToString();
            lock (locker)
            {
                XElement a = new XElement("Entrance",
                    new XAttribute("Id", item.Id),
                    new XElement("Timestamp", item.Timestamp),
                    new XElement("SessionId", item.SessionId),
                    new XElement("Page", item.Page),
                    new XElement("Details", item.Details),
                    new XElement("IP", item.IP));
                Document.Element("Entrances").Add(a);
                this.Save();

                //we must clean the file or it'll explode, so we wait for the morning
                if (DateTime.Now.Hour > 1 && DateTime.Now.Hour < 6)
                {
                    var items = Document.Descendants("Entrance");
                    if (items.Count() > 1000)
                    {
                        var toDelete = items.Take(items.Count() - 800).ToList();//leave the last 800
                        for (int i = 0; i < toDelete.Count; i++)
                        {
                            toDelete[i].Remove();
                        }
                        this.Save();
                    }
                }
            }
        }

        public void DeleteItem(MyAlbum.Model.Entrance item)
        {
            Assert.IsNotNull(item);
            lock (locker)
            {
                var saved = (from e in Document.Descendants("Entrance") where (e.Attribute("Id").Value) == item.Id select e).FirstOrDefault();
                if (saved != null)
                {
                    saved.Remove();
                    this.Save();
                }
            }
        }

        public void UpdateItem(MyAlbum.Model.Entrance item)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IRepository<Entrance> Members


        public MyAlbum.Model.Entrance GetItemById(string id)
        {
            return this.Document.Descendants("Entrance").Where(s => (s.Attribute("Id").Value) == id).Select(s => new MyAlbum.Model.Entrance()
            {
                Id = (s.Attribute("Id").Value),
                IP = s.Element("IP").Value.Trim(),
                Page = s.Element("Page").Value.Trim(),
                SessionId = s.Element("SessionId").Value.Trim(),
                Details = s.Element("Details").Value.Trim(),
                Timestamp = (DateTime)s.Element("Timestamp")
            }).SingleOrDefault();
        }

        #endregion
    }
}
